package com.example.demo.readShp;


import com.alibaba.fastjson.JSON;
import com.vividsolutions.jts.geom.Geometry;
import org.apache.commons.lang3.StringUtils;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;

/**
 * 解析shp文件
 * @author xujiajia
 *
 */
public class ShapeUtils {

    private static final Logger logger = LoggerFactory.getLogger(ShapeUtils.class);
    /**
     * 测试
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        String shpFilePath = "C:\\Users\\dingxiaoning\\Desktop\\jieya\\北七家南七家村复垦项目矢量\\2000矢量\\新增耕地5.shp";
        long time = System.currentTimeMillis();
        List<Map<String,Object>> readFile = readFile(shpFilePath, null);
        System.out.println(JSON.toJSONString(readFile.get(0)));


        long time2 = System.currentTimeMillis();
        System.out.println("耗时：" + (time2 - time));
       // System.out.println(readFile);

    }

    /**
     * 读取shp文件
     */
    public static List<Map<String, Object>> readFile(String shapePath, String prjPath) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        ShapefileDataStoreFactory factory = new ShapefileDataStoreFactory();
        ShapefileDataStore dataStore = null;
        SimpleFeatureIterator iterator =null;
        try {
            dataStore = (ShapefileDataStore) factory.createDataStore(new File(shapePath).toURI().toURL());
            if (dataStore != null) {
                dataStore.setCharset(Charset.forName("GBK"));
            }
            String wkt = "";
            if(StringUtils.isNotBlank(prjPath)) {
                wkt = TxtUtils.readTxtFile(prjPath);
                logger.info("获取到shp文件坐标系：{}", wkt);
            }
            boolean change = false;
            //如果是投影坐标系，则进行坐标转换
            if(wkt.startsWith("PROJCS")) {
                change = true;
            }
            SimpleFeatureSource featureSource = dataStore.getFeatureSource();
            iterator = featureSource.getFeatures().features();

            while (iterator.hasNext()) {
                SimpleFeature feature = iterator.next();
                Iterator<Property> it = feature.getProperties().iterator();
                Map<String, Object> map = new HashMap<String, Object>();
                while (it.hasNext()) {
                    Property pro = it.next();
                    if(change && "the_geom".equals(String.valueOf(pro.getName()))) {
                        map.put(String.valueOf(pro.getName()), CoordConverter.convert((Geometry)pro.getValue(), wkt));
                    } else {
                        map.put(String.valueOf(pro.getName()), String.valueOf(pro.getValue()));
                    }
                }
                list.add(map);
//				SimpleFeature feature = (SimpleFeature) iterator.next();
//	            // Feature转GeoJSON
//	            FeatureJSON fjson = new FeatureJSON();
//	            StringWriter writer = new StringWriter();
//	            fjson.writeFeature(feature, writer);
//	            String sjson = writer.toString();
//	            System.out.println("sjson=====  >>>>  "  + sjson);
            }
            iterator.close();
            return list;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            if(dataStore != null) {
                dataStore.dispose();
            }
            if(iterator != null) {
                iterator.close();
            }
        }
        return null;
    }

    /**
     * 丢给从一个文件中获取Shape文件路径
     *
     * @param path 文件夹路径
     * @param path 需要获得的shape文件路径
     */
    public static void getShapePath(String path, List<String> fielPath) {
        File file = new File(path);
        if (file.exists() && file.isDirectory()) {
            File[] files = file.listFiles();
            for (File file1 : files) {
                if (file1.isDirectory()) {
                    getShapePath(file1.getPath(), fielPath);
                } else {
                    String fileName = file1.getName();
                    String suffix = fileName.substring(fileName.lastIndexOf("."));
                    if (".shp".equals(suffix)) {
                        fielPath.add(file1.getAbsolutePath());
                        break;
                    }
                }
            }
        }
    }


    /**
     * 获取prj文件路径
     */
    public static void getPrjPath(String path, List<String> fielPath) {
        File file = new File(path);
        if (file.exists() && file.isDirectory()) {
            File[] files = file.listFiles();
            for (File file1 : files) {
                if (file1.isDirectory()) {
                    getShapePath(file1.getPath(), fielPath);
                } else {
                    String fileName = file1.getName();
                    String suffix = fileName.substring(fileName.lastIndexOf("."));
                    if (".prj".equals(suffix)) {
                        fielPath.add(file1.getAbsolutePath());
                        break;
                    }
                }
            }
        }
    }


    /**
     * 获取Shape文件的坐标系信息,GEOGCS表示这个是地址坐标系,PROJCS则表示是平面投影坐标系
     */
    public static String getCoordinateSystemWKT(String path) {
        ShapefileDataStoreFactory factory = new ShapefileDataStoreFactory();
        ShapefileDataStore dataStore = null;
        try {
            dataStore = (ShapefileDataStore) factory.createDataStore(new File(path).toURI().toURL());
            return dataStore.getSchema().getCoordinateReferenceSystem().toWKT();
        } catch (UnsupportedOperationException | IOException e) {
            logger.error(e.getMessage(), e);
        } finally {
            dataStore.dispose();
        }
        return "";
    }


    public static void deleteFile(File file){
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()){
            return;
        }
        //取得这个目录下的所有子文件对象
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f: files){
            //打印文件名
            String name = f.getName();
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()){
                deleteFile(f);
            }else {
                f.delete();
            }
        }
        //删除空文件夹  for循环已经把上一层节点的目录清空。
        file.delete();
    }
}